Un patrón de diseño es una solución reutilizable, compuesta por un diseño de interfaces, clases y objetos relacionados, para resolver un problema de diseño general que se presenta en un determinado contexto.
Un patrón consta de cuatro elementos esenciales:
Nombre: palabra o expresión corta que intenta transmitir la esencia del patrón.
Problema: descripción del problema en que se puede aplicar el patrón.
Solución: Un diagrama UML de clases que resuelve el problema.
Consecuencias: Ventajas o inconvenientes de aplicar el patrón.
Tienen que ver con el proceso de creación de objetos y tienen como objetivo encapsular la creación de objetos.
Define una interfaz para crear un objeto, pero deja que sean las subclase quienes decidan qué clase instanciar.
Permite que una clase delegue en sus subclases la creación de objetos.
Abstract Factory los utiliza.
Proporciona una interface para crear objetos en una superclase, mientras permite a las subclases alterar el tipo de objetos que se crearán.
Ejemplos:
“Temas” de interfaces gráficos, donde todos los elementos cambian a la vez (oscuro, claro, alto contraste...).
Gestión de bases de datos distintas donde la funcionalidad (conectar, acceder, cerrar) no bebería depender del tipo concreto.
Separa la construcción de un objeto complejo de su representación, de forma que el mismo proceso de construcción pueda crear diferentes representaciones.
Ejemplo:
Aplicación de conversión de vídeo:
Diferentes formatos de contendor( AVI, MPG, MOV...).
Diferentes códecs (audio/vídeo).
Operaciones adicionales (escalado, recortado...).
Garantiza que una clase sólo tenga una instancia, a la vez que proporciona un punto de acceso global a dicha instancia.
Ejemplos:
Única instancia de una clase controladora de la ejecución de un programa.
Clase para acceder a la base de datos y obtener información.
Clase para obtener información de una API.
Tratan con la composición de clases u objetos para crear estructuras más complejas.
Convierte la interfaz de una clase en otra distinta que es la que esperan los clientes.
Permite que cooperen clases que de otra manera no podrían por tener interfaces incompatibles.
Se intercala una nueva clase que hace el trabajo de traducción o adaptación.
Ejemplos:
Editor de dibujo que consume una librería de terceros para la creación de objetos gráficos.
Una aplicación que consume información de diferentes APIs con mismos servicios pero diferente nomenclatura.
Desacopla una abstracción de su implementación, de manera que ambas puedan variar de forma independiente.
Combina objetos en estructuras de árbol para representar jerarquías de parte-todo.
Permite que los clientes traten de manera uniforme a los objetos individuales y a los compuestos.
Añade dinámicamente nuevas responsabilidades a un objeto, proporcionando una alternativa flexible a la herencia para extender la funcionalidad.
Ejemplos:
Un negocio que ofrece "complementos" que se pueden añadir o configurar:
Configuración de coches en el concesionario.
Menús de restaurantes.
Configuración de paquetes de vacaciones.
Configuración de compra de un billete de avión.
Proporciona una interfaz unificada para un conjunto de interfaces de un subsistema.
Define una interfaz de alto nivel que hace que el subsistema sea más fácil de usar.
Es similar al adaptador, pero el adaptador adapta una clase concreta, la fachada esta pensada para reducir el acoplamiento.
Ejemplos:
Acceso telefónico para hacer un pedido:
El operador es la fachada.
Él desencadena las acciones “detalladas” a partir de tus peticiones “de más alto nivel”.
Proporciona un sustituto o representante de otro objeto para controlar el acceso a éste.
El proxy (apoderado) sustituye al objeto real (sujeto) y permite manipularlo de manera indirecta.
Ejemplos:
Operaciones de acceso a red, en las que el proxy actúa como fachada o adaptador.
Sustitución temporal de objetos cuya carga en memoria resulta costosa, retrasando su carga hasta que sea imprescindible (lazy load).
Orientados a la comunicación e interacción entre objetos y el control de flujo del proceso.
Evita acoplar al emisor de una petición a su receptor, al dar a más de un objeto la posibilidad de responder a la petición.
Crea una cadena con los objetos receptores y pasa la petición a través de la cadena hasta que esta sea tratada por algún objeto.
Ejemplos:
Ayuda contextual en una aplicación:
Buscar información más específica según el elemento consultado.
Proceso de eventos del ratón en un navegador.
Encapsula una petición en un objeto, permitiendo así́ parametrizar a los clientes con distintas peticiones, encolar o llevar un registro de las peticiones y poder deshacer las operaciones.
Ejemplos:
Simulación de mandos o paneles decontrol:
Podrían tener acciones configurables.
Para ocultar detalles concretos del aparato a servicio que determinan.
Dado un lenguaje, define una representación de su gramática junto con un intérprete que usa dicha representación para interpretar sentencias del lenguaje.
Ejemplos:
Gestión de expresiones que siguen una gramática formal:
Lenguajes de acceso a sistemas o de descripción.
Proporciona un modo de acceder secuencialmente a los elementos de un objeto agregado sin exponer su representación interna.
Ejemplos:
Concepto de iterador de colecciones en entornos de POO.
Define una dependencia de uno-a-muchos entre objetos, de forma que cuando un objeto cambie de estado se notifica y se actualizan automáticamente todos los objetos que dependen de él.
El patrón define dos tipos de objetos:
Sujeto: donde se producen los cambios.
Observador: es notificado y propaga la información.
Ejemplos:
Un sistema de control domótico:
Cuando un sensor cambia de estado avisa al resto.
Servicio WEB de datos científicos:
Cuando en una estación meteorológica cambian los datos, se actualizan los servicios que cuelgan de ella.
Define una familia de algoritmos, encapsula cada uno de ellos y los hace intercambiables. Permite que un algoritmo varíe independientemente de los clientes que lo usan.
Ejemplos:
Situación de logística:
Establecer una ruta para el transporte, ocultando detalles propios de si se hará por barco, avión, tren...
Un antipatrón es un patrón de diseño que conduce a una mala solución.
Es importante conocer los antipatrones para poder evitarlos.

Single responsability (Única responsabilidad): un componente debe estar centrado en una única tarea.
Open/Close (Abierto/Cerrado): Un componente debe ser abierto para la extensión y cerrado para la modificación.
Liskow substitution priciple (Principio de sustitución de Liskow): Cada clase que hereda de otra puede usarse como su padre sin necesidad de conocer las diferencias entre ellas.
Interface segregation principle (Principio de segregación de la interface): Es mejor tener muchas interfaces especificas que una de propósito general.
Dependency inversión principle (Principio de inversión de dependencias): Depender de las abstracciones (interfaces), no de las concrecciones (clases).